// 实现监控对象
function observer(data) {
    if (!data || typeof data !== "object") {
        return;
    }

    // 取出所有值, 并准备定义监控
    Object.keys(data).forEach(function (key) {
        defineReactive(data, key, data[key]);
    })
}

function defineReactive(data, key, val) {
    // 如果是对象继续监控
    observer(val);

    // 定义此KEY的订阅器实例
    var dep = new Dep();
    Object.defineProperty(data, key, {
        enumerable: true,
        configurable: true,
        get: function () {
            // 有人获取此值时, 将对象中的target加入到队列中, target赋的值需要为function
            if (Dep.target) {
                dep.addSub(Dep.target);
                Dep.target = null;
            }

            return val;
        },
        set: function (newVal) {
            // console.log("属性", key, "已经被监听了, 旧值", val, ", 新值:" + newVal);
            // 新旧值无变化时, 不设置
            if (val === newVal) {
                return;
            }

            // 设置新值, 并调用订阅器中的方法
            val = newVal;
            dep.notify();
        }

    });
    console.log(data)
}


// 订阅器
function Dep() {
    // 订阅器数组, 有多个订阅对象时, 全部加入进来
    this.subs = [];
};

Dep.prototype = {
    addSub: function (sub) {
        this.subs.push(sub);
    },
    notify: function () {
        this.subs.forEach(function (sub) {
            sub.update();
        })
    }
};

Dep.target = null;
